/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.user.comment.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.BatchBindCouponEvent;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.dao.UserExtensionMapper;
import com.yami.shop.service.NotifyTemplateService;
import com.yami.shop.service.UserService;
import com.yami.shop.user.comment.dao.UserLevelMapper;
import com.yami.shop.user.comment.dto.LevelDetailDto;
import com.yami.shop.user.comment.dto.UserLevelDto;
import com.yami.shop.user.comment.enums.UserRightsInfo;
import com.yami.shop.user.comment.model.*;
import com.yami.shop.user.comment.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Service
@AllArgsConstructor
@Slf4j
public class UserLevelServiceImpl extends ServiceImpl<UserLevelMapper, UserLevel> implements UserLevelService {

    private final UserLevelMapper userLevelMapper;
    private final UserLevelLogService userLevelLogService;
    private final NotifyTemplateService notifyTemplateService;
    private final UserScoreDetailService userScoreDetailService;
    private final UserScoreLogService userScoreLogService;
    private final UserGrowthLogService userGrowthLogService;
    private final UserService userService;
    private final UserExtensionMapper userExtensionMapper;
    private final ApplicationContext applicationContext;
    private final UserLevelCategoryService userLevelCategoryService;
    private final UserLevelCouponService userLevelCouponService;
    private final UserRightsService userRightsService;
    private final UserLevelRightsService userLevelRightsService;

//    @Override
//    @Cacheable(cacheNames = "UserLevelsByLevelType", key = "#userLevelType")
//    public List<UserLevel> listUserLevelsByUserLevelType(Integer userLevelType) {
//        return userLevelMapper.selectList(new LambdaQueryWrapper<UserLevel>().eq(UserLevel::getLevelType, userLevelType));
//    }
//
    @Override
    @Cacheable(cacheNames = "UserLevelsByLevelType", key = "#userLevelType")
    public List<UserLevelDto> listUserLevelsByUserLevelType(Integer userLevelType) {
        List<UserLevelDto> userLevelList = userLevelMapper.getList(userLevelType);
//        Iterator<UserLevelDto> iterator = userLevelList.iterator();
//        while (iterator.hasNext()){
//            UserLevelDto userLevel = iterator.next();
//            if (Objects.equals(userLevel.getDiscountType(),1)){
//                List<Long> categoryIds =  userLevelCategoryService.getCategoryIdByLevelId(userLevel.getId());
//                userLevel.setCategorys(categoryIds);
//            }
//            userLevel.setCouponList(userLevelCouponService.getCouponListByLevelId(userLevel.getId()));
//        }
        return userLevelList;
    }
    @Override
    @CacheEvict(cacheNames = "UserLevelsByLevelType", key = "#userLevelType")
    public void removeUserLevelsByUserLevelTypeCache(Integer userLevelType) {

    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccess(String payNo) {
        //根据内部订单号更新用户会员信息
        UserLevelLog userLevelLog = userLevelLogService.getOne(new LambdaQueryWrapper<UserLevelLog>().eq(UserLevelLog::getPayNo,payNo));
        if(userLevelLog == null){
            log.info("订单异常,");
            return;
        }
        // 订单已支付
        if (userLevelLog.getIsPayed() == 1) {
            log.info("订单已支付，settlement.id：{}", userLevelLog.getPayNo());
            return;
        }
        UserLevel userLevel = userLevelMapper.selectLevelAndCoupons(userLevelLog.getLevel());
        if(userLevel == null){
            log.info("订单异常,会员等级找不到!",userLevelLog.getPayNo());
            return;
        }
        //修改用户会员信息
        User user = userService.getById(userLevelLog.getUserId());
        UserExtension userExtension = userExtensionMapper.selectOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,userLevelLog.getUserId()));
        //修改用户等级
        updateUserLevel(user,userLevel,userExtension);
        //发放奖励
        ArrayList<UserLevel> userLevels = new ArrayList<>();
        userLevels.add(userLevel);
        levelUp(userLevels,userLevelLog,userExtension,null);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "UserLevelsByLevelType", key = "#userLevel.levelType")
    public void updateUserLevelList(UserLevel userLevel) {
        UserLevel dbUserLevel = new UserLevel();
        //根据成长值，更新已有用户的等级
        if (Objects.nonNull(userLevel.getId())){
            dbUserLevel = userLevelMapper.selectOne(new LambdaQueryWrapper<UserLevel>()
                    .eq(UserLevel::getId,userLevel.getId())
                    .eq(UserLevel::getLevelType,userLevel.getLevelType()));
        } else {
            int count = count(new LambdaQueryWrapper<UserLevel>().eq(UserLevel::getLevelType, userLevel.getLevelType()));
            count++;
            if (userLevel.getLevel() != count){
                userLevel.setLevel(count);
            }
        }
        // 若是普通会员，新增或修改时成长值有变化，状态设置为未更新用户等级'
        if (Objects.equals(userLevel.getLevelType(),0) && !Objects.equals(dbUserLevel.getNeedGrowth(),userLevel.getNeedGrowth())){
            userLevel.setStatus(-1);
        } else {
            userLevel.setStatus(1);
        }
        this.saveOrUpdate(userLevel);
        // 插入/更新等级分类数据
        this.delOrAddCategory(userLevel,dbUserLevel);
        //插入/更新等级优惠券数据
        this.delOrAddCoupon(userLevel);
        //插入/更新等级用户权益数据
        this.delOrAddRights(userLevel);
    }

    @Override
    @CacheEvict(cacheNames = "UserLevelsByLevelType", key = "#userLevel.levelType")
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUserLevel(UserLevel userLevel) {
        if (Objects.equals(userLevel.getLevel(),1)){
            // 此等级不能删除，必须要保留最少一个等级
            throw new YamiShopBindException("yami.user.level.delete.error");
        }
        UserLevel dbUserLevel = userLevelMapper.selectById(userLevel.getId());
        //删除等级关联权益
        userLevelRightsService.remove(new LambdaQueryWrapper<UserLevelRights>().eq(UserLevelRights::getLevelId,userLevel.getId()));
        //删除等级关联的优惠券
        userLevelCouponService.remove(new LambdaQueryWrapper<UserLevelCoupon>().eq(UserLevelCoupon::getLevelId,userLevel.getId()));
        //删除等级关联的分类
        userLevelCategoryService.remove(new LambdaQueryWrapper<UserLevelCategory>().eq(UserLevelCategory::getLevelId,userLevel.getId()));
        userService.setUserLevelBylevelId(dbUserLevel.getLevel(),dbUserLevel.getLevelType());
        this.removeById(userLevel.getId());
        return true;
    }

    @Override
    public UserLevel getUserLevelById(Long id) {
        UserLevel userLevel = userLevelMapper.selectById(id);
        if (Objects.equals(userLevel.getDiscountType(),1)){
            List<Long> categoryIds =  userLevelCategoryService.getCategoryIdByLevelId(userLevel.getId());
            userLevel.setCategorys(categoryIds);
        }
        userLevel.setUserRightsIds(userRightsService.getUserRightsIdListByLevelId(userLevel.getId(),1));
        userLevel.setCouponList(userLevelCouponService.getCouponListByLevelId(userLevel.getId()));
        return userLevel;
    }

    @Override
    public List<LevelDetailDto> selectLevelAndRights(Integer levelType) {
        return userLevelMapper.selectLevelAndRights(levelType);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateGrowth(UserUpdateParam param) {
        Integer growthValue = param.getGrowthValue();
        List<String> userIds = param.getUserIds();
        if (Objects.isNull(growthValue) || CollectionUtils.isEmpty(userIds)) {
            return false;
        }
        if (Objects.equals(0,growthValue)) {
            return false;
        }
        for (String userId : userIds) {
            UserExtension userExtension = userExtensionMapper.getByUserId(userId);
            // 系统直接修改成长值
            addGrowthAndScore(growthValue,0,userId,userExtension,param.getIsSendReward());
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateScore(UserUpdateParam param) {
        List<String> userIds = param.getUserIds();
        Integer scoreValue = param.getScoreValue();
        if (Objects.isNull(scoreValue) || CollectionUtils.isEmpty(userIds)) {
            return false;
        }
        if (Objects.equals(0,scoreValue)) {
            return false;
        }
        for (String userId : userIds) {
            UserExtension userExtension = userExtensionMapper.getByUserId(userId);
            // 系统直接修改积分
            addGrowthAndScore(0,scoreValue,userId,userExtension,param.getIsSendReward());
        }
        return true;
    }

    /**
     * @param growthValue 增加/减少的成长值
     * @param score 增加/减少的积分
     * @param userId 用户id
     * @param userExtension
     * @param isSendReward 是否发放奖励，是1 否0
     */
    private void addGrowthAndScore(Integer growthValue, Integer score, String userId, UserExtension userExtension, Integer isSendReward) {
        User user = userService.getById(userId);
        if(Objects.isNull(user.getLevel())){
            user.setLevel(Constant.USER_LEVEL_INIT);
        }
        Integer growth = (int) growthValue;

        //判断是否升级
        //修改用户信息
        //用户＋增加成长值
        Integer nowGrowth = userExtension.getGrowth() == null ?growth:userExtension.getGrowth() + growth;
        Integer nowScore = userExtension.getScore() == null ? score : userExtension.getScore() + score;
        //用户积分最低为0
        if (nowScore < 0) {
            nowScore = 0;
        }
        //用户成长值最低为0
        if (nowGrowth < 0) {
            nowGrowth = 0;
        }

        addScoreAndGrowth(user.getUserId(),growth,score);
        userExtension.setGrowth(nowGrowth);
        userExtension.setScore(nowScore);
        userExtension.setUpdateTime(new Date());
        //如果用户是付费会员则不提升等级,也不会降低等级，只修改成长值
        //判断用户是否提升过等级,如果是修改用户等级并添加用户等级提升日志
        // 是否降级
        boolean isReduceLevel = false;
        List<UserLevel> userLevels = new ArrayList<>();
        if (growth > 0) {
            userLevels = userLevelMapper.selectListAndCoupons(nowGrowth,userExtension.getLevel());
        } else {
            // 查看比当前成长值小的一个等级是否和当前等级相同，如果相同就不改变，如果比当前等级小，就降低一级
            userLevels = userLevelMapper.selectListAndCouponsLtNowGrowth(nowGrowth,userExtension.getLevel());
            isReduceLevel = CollectionUtils.isNotEmpty(userLevels) && userLevels.get(0).getLevel() < userExtension.getLevel();
            userLevels = isReduceLevel ? userLevels : null;
        }
        if(user.getLevelType() == 1 || CollectionUtils.isEmpty(userLevels)){
            userExtensionMapper.updateById(userExtension);
        }else{
            Integer level = userLevels.get(0).getLevel();
            //修改用户等级
            user.setLevel(level);
            userService.updateById(user);
            //判断用户是否提升过等级
            Integer historyLevel = userLevelLogService.getMaxLevelByUserId(user.getUserId());
            //等级提升发放奖品及添加等级提升日志
            levelUp(userLevels,null,userExtension,historyLevel);
        }

    }

    private void addScoreAndGrowth(String userId, Integer growth, Integer score) {
        if (score != 0) {
            // 添加积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setStatus(1);
            addDetail.setUserId(userId);
            addDetail.setUsableScore(score);
            addDetail.setCreateTime(new Date());
            userScoreDetailService.save(addDetail);

            // 添加积分日志
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setScore(Math.abs(score));
            userScoreLog.setUserId(userId);
            userScoreLog.setSource(ScoreLogType.SYSTEM.value());
            userScoreLog.setCreateTime(new Date());
            userScoreLog.setIoType(score>0?1:0);
            userScoreLogService.save(userScoreLog);
        }
        if (growth != 0) {
            //添加成长值日志
            UserGrowthLog userGrowthLog = new UserGrowthLog();
            userGrowthLog.setChangeGrowth(growth);
            userGrowthLog.setSource(1);
            userGrowthLog.setUserId(userId);
            userGrowthLog.setCreateTime(new Date());
            userGrowthLog.setRemarks("系统修改用户成长值");
            userGrowthLogService.save(userGrowthLog);
        }
    }

    @Override
    @Cacheable(cacheNames = "getUserLevelName", key = "#userExtension.userId")
    public String getUserLevelName(UserExtension userExtension) {
        List<UserLevel> userLevels = list(new LambdaQueryWrapper<UserLevel>()
                .le(UserLevel::getNeedGrowth,userExtension.getGrowth()).orderByDesc(UserLevel::getNeedGrowth));
        String levelName;
        if(userExtension.getLevel() == null){
            levelName = userLevels.get(0).getLevelName();
        }else{
            levelName = String.valueOf(userExtension.getLevel());
        }
        return levelName;
    }

    @Override
    @CacheEvict(cacheNames = "UserLevelsByLevelType", key = "#userLevel.levelType")
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserLevel(UserLevel userLevel) {
        List<UserLevelDto> userLevelDtoList = this.listUserLevelsByUserLevelType(userLevel.getLevelType());
        Boolean isUpdate = false;
        Integer level = 0;
        Integer minNeedGrowth = 0;
        for (UserLevelDto userLevelDto:userLevelDtoList){
            //成长值处于会员等级变化的区间，更新用户等级
            if (isUpdate){
                userService.setUserLevelByGrowth(level,minNeedGrowth-1,userLevelDto.getNeedGrowth(),userLevel.getLevelType());
                isUpdate = false;
            }
            if (Objects.equals(userLevelDto.getStatus(),-1) && Objects.equals(userLevelDto.getLevel(),userLevelDtoList.size())){
                userService.setUserLevelByGrowth(userLevelDto.getLevel(),userLevelDto.getNeedGrowth()-1,null,userLevel.getLevelType());
            }else if(Objects.equals(userLevelDto.getStatus(),-1)){
                isUpdate = true;
            }
            level = userLevelDto.getLevel();
            minNeedGrowth = userLevelDto.getNeedGrowth();
        }
        userLevelMapper.setStatusByLevelType();
        return true;
    }

    /**
     * 修改用户等级中的商品分类
     * @param userLevel
     * @param dbUserLevel
     */
    private void delOrAddCategory(UserLevel userLevel, UserLevel dbUserLevel) {
        List<Long> dbCategoryIds =  userLevelCategoryService.getCategoryIdByLevelId(userLevel.getId());
        List<Long> categoryList = userLevel.getCategorys();
        //如果分类数据发生改变，执行方法进行增删操作
        Map<String,List<Long>> map = this.compare(categoryList,dbCategoryIds);
        List<Long> delCategory = map.get("del");
        if (delCategory.size()>0){
            userLevelCategoryService.delBatch(delCategory.toArray(new Long[delCategory.size()]),userLevel.getId());
        }
        List<Long> addCategory = map.get("add");
        if (addCategory.size()>0){
            userLevelCategoryService.insertBatch(addCategory.toArray(new Long[addCategory.size()]),userLevel.getId());
        }
    }

    /**
     * 修改用户等级中的赠送优惠券
     * @param userLevel
     */
    private void delOrAddCoupon(UserLevel userLevel) {
        List<UserLevelCoupon> userLevelCouponList = userLevelCouponService.list(new LambdaQueryWrapper<UserLevelCoupon>().eq(UserLevelCoupon::getLevelId, userLevel.getId()));
        List<Long> dbCouponIds = new ArrayList<>();
        List<Long> couponIds = new ArrayList<>();
        if (!Objects.isNull(userLevelCouponList)){
            for (UserLevelCoupon userLevelCoupon:userLevelCouponList){
                dbCouponIds.add(userLevelCoupon.getCouponId());
            }
        }
        if (!Objects.isNull(userLevel.getCouponList())){
            for (Coupon coupon:userLevel.getCouponList()){
                couponIds.add(coupon.getCouponId());
            }
        }
        Map<String,List<Long>> map = this.compare(couponIds,dbCouponIds);
        List<Long> delCoupon = map.get("del");
        if (delCoupon.size()>0){
            userLevelCouponService.delBatchCoupon(delCoupon.toArray(new Long[delCoupon.size()]),userLevel.getId());
        }
        List<Long> addCoupon = map.get("add");
        if (addCoupon.size()>0){
            userLevelCouponService.insertBatchCoupon(addCoupon.toArray(new Long[addCoupon.size()]),userLevel.getId());
        }

    }

    /**
     * 修改用户等级中的权益
     * @param userLevel
     */
    private void delOrAddRights(UserLevel userLevel) {
        List<Long> userRightsList = userRightsService.getUserRightsIdListByLevelId(userLevel.getId(),null);
        List<Long> dbRightsIds = new ArrayList<>();
        List<Long> rightsIds = new ArrayList<>();
        if (!Objects.isNull(userRightsList)){
           dbRightsIds.addAll(userRightsList);
        }
        if (!Objects.isNull(userLevel.getUserRightsIds())){
            rightsIds.addAll(userLevel.getUserRightsIds());
            //折扣
            if (!Objects.equals(userLevel.getDiscount(), 10D)) {
                rightsIds.add(UserRightsInfo.DISCOUNT.value());
            }
            //包邮
            if (Objects.equals(userLevel.getIsFreeFee(), 1)) {
                rightsIds.add(UserRightsInfo.IS_FREE_FEE.value());
            }
            //赠送积分
            if (!Objects.equals(userLevel.getPresScore(), 0)) {
                rightsIds.add(UserRightsInfo.SCORE.value());
            }
            //优惠券
            if (userLevel.getCouponList().size()>0) {
                rightsIds.add(UserRightsInfo.COUPON.value());
            }
            //积分倍率
            if (!Objects.equals(userLevel.getRateScore(), 1D)) {
                rightsIds.add(UserRightsInfo.RATE_SCORE.value());
            }
        }
        Map<String,List<Long>> map = this.compare(rightsIds,dbRightsIds);
        List<Long> delCoupon = map.get("del");
        if (delCoupon.size()>0){
            userLevelRightsService.delBatchRights(delCoupon.toArray(new Long[delCoupon.size()]),userLevel.getId());
        }
        List<Long> addCoupon = map.get("add");
        if (addCoupon.size()>0){
            userLevelRightsService.insertBatchRights(addCoupon.toArray(new Long[addCoupon.size()]),userLevel.getId());
        }
    }


    /**
     * 得到需要新增或删除的数据
     * @param ids
     * @param dbIds
     */
    private Map<String,List<Long>> compare(List<Long> ids, List<Long> dbIds) {
        if (Objects.isNull(ids)){
            ids = new ArrayList<>();
        }
        List<Long> del = new ArrayList<>();
        List<Long> add = new ArrayList<>();
        del.addAll(dbIds);
        add.addAll(ids);
        add.removeAll(dbIds);
        del.removeAll(ids);
        Map<String,List<Long>> map = new HashMap<>();
        //需要新增的数据
        map.put("add",add);
        //需要删除的数据
        map.put("del",del);
        return map;
    }

    /**
     * 增加用户成长值和积分
     * @param growthPrice 增加的成长值
     * @param score    增加的积分
     * @param userId    用户id
     * @param bizId    bizId
     * @param type    1:等级 2：余额充值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addGrowthAndScore(double growthPrice, Integer score,String userId,String bizId,UserExtension userExtension,Integer type) {
        User user = userService.getById(userId);
        if(user.getLevel() == null){
            user.setLevel(Constant.USER_LEVEL_INIT);
        }
        Integer growth = (int) growthPrice;

        addScoreAndGrowth(bizId,userId,growth,score,type);
        // 判断是否升级
        // 修改用户信息
        // 用户＋增加成长值
        Integer nowGrowth = userExtension.getGrowth() == null ?growth:userExtension.getGrowth() + growth;
        userExtension.setScore(userExtension.getScore() == null ? score : userExtension.getScore() + score);
        userExtension.setGrowth(nowGrowth);
        userExtension.setUpdateTime(new Date());
        // 如果用户是付费会员则不提升等级,只修改成长值
        // 判断用户是否提升过等级,如果是修改用户等级并添加用户等级提升日志
        List<UserLevel> userLevels = userLevelMapper.selectListAndCoupons(nowGrowth,userExtension.getLevel());
        if(user.getLevelType() == 1 || CollectionUtils.isEmpty(userLevels)){
            userExtensionMapper.updateBalanceByVersion(userExtension);
        }else{
            Integer level = userLevels.get(0).getLevel();
            //修改用户等级
            user.setLevel(level);
            userService.updateById(user);
            //判断用户是否提升过等级
            Integer historyLevel = userLevelLogService.getMaxLevelByUserId(user.getUserId());
            //等级提升发放奖品及添加等级提升日志
            levelUp(userLevels,null,userExtension,historyLevel);
        }
    }

    /**
     * 添加积分明细、积分日志、成长值日志
     * @param bizId type = 1:订单号 type = 2:充值id
     * @param userId 用户id
     * @param growth 成长值
     * @param score 积分
     * @param type type = 1:订单 type = 2:余额
     */
    private void addScoreAndGrowth(String bizId, String userId, Integer growth, Integer score, Integer type) {
        if(score > 0) {
            //添加积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setCreateTime(new Date());
            addDetail.setStatus(1);
            addDetail.setUserId(userId);
            addDetail.setBizId(bizId);
            addDetail.setUsableScore(score);
            userScoreDetailService.save(addDetail);

            //添加积分日志
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(userId);
            userScoreLog.setScore(score);
            userScoreLog.setBizId(bizId);
            if(type.equals(1)){
                userScoreLog.setSource(ScoreLogType.SHOP.value());
            }else {
                userScoreLog.setSource(ScoreLogType.BALANCE.value());
            }
            userScoreLog.setCreateTime(new Date());
            userScoreLog.setIoType(1);
            userScoreLogService.save(userScoreLog);
        }
        if(growth > 0) {
            //添加成长值日志
            UserGrowthLog userGrowthLog = new UserGrowthLog();
            userGrowthLog.setChangeGrowth(growth);
            userGrowthLog.setSource(1);
            userGrowthLog.setUserId(userId);
            userGrowthLog.setCreateTime(new Date());
            userGrowthLog.setBizId(bizId);
            if (type.equals(1)){
                userGrowthLog.setRemarks("订单确认收货获取的成长值");
            }else {
                userGrowthLog.setRemarks("用户充值余额获取的成长值");
            }
            userGrowthLogService.save(userGrowthLog);
        }
    }
//
//    private void updateUser(User user, UserLevel userLevel) {
//        Integer level = userLevel.getLevel();
//        DateTime endTime;
//        //修改用户等级
//        if(user.getVipEndTime() == null || user.getLevel() < level){
//            endTime = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, 24 * userLevel.getTerm());
//        }else{
//            endTime = DateUtil.offset(user.getVipEndTime(), DateField.HOUR_OF_DAY, 24 * userLevel.getTerm());
//        }
//        user.setVipEndTime(endTime);
//        user.setLevel(level);
//        userService.updateById(user);
//
//        //修改用户等级积分详细表
//        UserExtension extension = userExtensionMapper.selectOne(
//                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, user.getUserId()));
//        if(extension == null){
//            UserExtension userExtension = new UserExtension();
//            userExtension.setUserId(user.getUserId());
//            userExtension.setGrowth(0);
//            userExtension.setScore(0);
//            userExtension.setBalance(0.0);
//            userExtension.setVersion(0);
//            userExtension.setLevel(level);
//            userExtension.setUpdateTime(new Date());
//            userExtensionMapper.insert(userExtension);
//        }else{
//            extension.setLevel(level);
//            extension.setUpdateTime(new Date());
//            // 使用乐观锁进行更新
//            if (userExtensionMapper.updateById(extension)!=1) {
//                log.error("更新用户等级失败！");
//                throw new YamiShopBindException("服务器繁忙,更新用户等级失败!");
//            }
//        }
//
//    }


    /**
     * 用户购买会员后提升会员等级
     * @param user 用户信息
     * @param userLevel 用户等级
     * @param userExtension 用户扩展信息
     */
    private void updateUserLevel(User user, UserLevel userLevel, UserExtension userExtension) {
        Integer level = userLevel.getLevel();
        DateTime endTime;
        Map<Integer,Integer> dateMap = new HashMap<>(12);
        dateMap.put(1,1);
        dateMap.put(2,7);
        dateMap.put(3,31);
        dateMap.put(4,93);
        dateMap.put(5,366);
        //修改用户等级
        if (user.getVipEndTime() == null || user.getLevel() < level || user.getLevel() >level) {
            endTime = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, 24 * userLevel.getTerm() * dateMap.get(userLevel.getTermType()));
        } else{
            endTime = DateUtil.offset(user.getVipEndTime(), DateField.HOUR_OF_DAY, 24 * userLevel.getTerm()* dateMap.get(userLevel.getTermType()));
        }
        user.setVipEndTime(endTime);
        user.setLevel(level);
        user.setLevelType(1);
        userService.updateById(user);
        //修改用户等级积分详细表
        userExtension.setLevel(level);
        userExtension.setLevelType(1);
        userExtension.setUpdateTime(new Date());
        // 使用乐观锁进行更新
        if (userExtensionMapper.updateById(userExtension) != 1) {
            log.error("更新用户等级失败！");
            // 服务器繁忙,更新用户等级失败!
            throw new YamiShopBindException("yami.network.busy");
        }
    }

    /**
     * 等级提升
     * @param userLevels 多个等级，奖励发放时
     * @param userLevelLog 等级日志,在购买付费会员时存在
     * @param user 用户详细信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void levelUp(List<UserLevel> userLevels, UserLevelLog userLevelLog, UserExtension user,Integer historyLevel) {
        List<UserScoreLog> userScoreLogs = new ArrayList<>();
        List<UserScoreDetail> userScoreDetails = new ArrayList<>();
        //用户可能升多级，批量插入升级日志
        List<UserLevelLog> levelLogs = new ArrayList<>();
        List<Long> couponIds = new ArrayList<>();
        User userDetail = userService.getById(user.getUserId());
        for (UserLevel level : userLevels) {
            //修改用户扩展表等级
            user.setLevel(level.getLevel());
            user.setLevelType(level.getLevelType());
            boolean isLevelUp = historyLevel != null &&(level.getLevel() <= historyLevel || level.getLevel().equals(user.getLevel()));
            //如果历史提升过此等级并且为普通会员就退出循环
            if(level.getLevelType() == 0 && !isLevelUp){
                break;
            }
            // 消息推送-升级提醒，只有升级时进行提醒
            if(!isLevelUp){
                notifyTemplateService.sendNotifyOfLevelUp(level.getLevelName(),userDetail);
            }
            //升级奖励计算(积分，优惠券，商品)
            //1.积分
            if(level.getPresScore() != null && level.getPresScore()  > 0) {
                UserScoreLog userScoreLog = new UserScoreLog();
                Integer score = level.getPresScore();
                userScoreLog.setUserId(user.getUserId());
                userScoreLog.setScore(score);
                userScoreLog.setSource(ScoreLogType.LEVEL_UP.value());
                userScoreLog.setCreateTime(DateUtil.date());
                userScoreLog.setIoType(1);
                userScoreLogs.add(userScoreLog);

                //添加积分明细
                UserScoreDetail addDetail = new UserScoreDetail();
                addDetail.setCreateTime(new Date());
                addDetail.setStatus(1);
                addDetail.setUserId(user.getUserId());
                addDetail.setUsableScore(score);
                userScoreDetails.add(addDetail);

                user.setScore(user.getScore() == null ? score : user.getScore() + score);
            }
            //2.优惠券
            if(CollectionUtils.isNotEmpty(level.getCouponIds())){
                couponIds.addAll(level.getCouponIds());
            }
            //3.等级日志,如果不为空则为会员购买提升的等级就直接退出，修改一行
            if(userLevelLog != null){
                userLevelLog.setIsPayed(1);
                userLevelLog.setState(1);
                userLevelLog.setLevelType(1);
                userLevelLogService.updateById(userLevelLog);
                break;
            }
            UserLevelLog levelLog = new UserLevelLog();
            levelLog.setUserId(user.getUserId());
            levelLog.setAddrOrderId(null);
            levelLog.setLevel(level.getLevel());
            levelLog.setCreateTime(DateUtil.date());
            levelLog.setState(1);
            levelLog.setLevelType(0);
            levelLog.setIsPayed(1);
            levelLogs.add(levelLog);
        }
        //修改扩展表信息
        userExtensionMapper.updateById(user);
        if(CollectionUtils.isNotEmpty(couponIds)){
            applicationContext.publishEvent(new BatchBindCouponEvent(couponIds,user.getUserId(),0L));
        }
        //保存积分日志、积分明细日志
        if(CollectionUtils.isNotEmpty(userScoreLogs)){
            userScoreLogService.saveBatch(userScoreLogs);
            userScoreDetailService.saveBatch(userScoreDetails);
        }
        //批量保存等级日志
        if(CollectionUtils.isNotEmpty(levelLogs)){
            userLevelLogService.saveBatch(levelLogs);
        }
    }


}
